﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using Vds2465Telegrams;

namespace Vds2465Parser
{
    internal static class GenParse_UserData_24_BlockState
    {
        #region private constants

        private const int NrOfHeaderBytes = 6;

        #endregion private constants

        #region internal methods

        internal static byte[] GenerateBytes(UserData userData)
        {
            byte[] userDataBytes = null;

            if (userData is UserData_24_BlockState)
            {
                UserData_24_BlockState userData24 = userData as UserData_24_BlockState;
                byte[] blockStateBytes = userData24.GetCopyOfBlockStateBytes();
                
                // calculate number of bytes
                int totalNrOfBytes = NrOfHeaderBytes;
                if (blockStateBytes != null)
                {
                    totalNrOfBytes += blockStateBytes.Length;
                }

                if (totalNrOfBytes > 255)
                {
                    // TODO handle error
                    // TODO is 255 the correct number or do we need a smaller number
                }

                userDataBytes = new byte[totalNrOfBytes];
                userDataBytes[0] = (byte)(totalNrOfBytes - GenParse_UserData.HeaderLength);	// user data length
                userDataBytes[1] = UserData.UserData24BlockState;
                userDataBytes[2] = userData24.Device;
                userDataBytes[3] = userData24.Address;
                userDataBytes[4] = userData24.AddressAddOn;
                userDataBytes[5] = GenParse_AddressExtension.GenerateByte_AddExt_1(userData24.AddressExtension);
                for (int index=0; index < blockStateBytes.Length; index++)
                {
                    userDataBytes[index + 6] = blockStateBytes[index];
                }
            }
            else
            {
                // TODO handle error
            }

            return userDataBytes;
        }

        internal static bool ParseBytes(byte[] userDataBytes, out UserData userData24BlockState, out int consumedBytes)
        {
            userData24BlockState = null;
            consumedBytes = 0;

            if (userDataBytes.Length >= NrOfHeaderBytes)
            {
				byte setLength = userDataBytes[0];
				if (userDataBytes.Length >= setLength + 2)
				{
					if (userDataBytes[1] == UserData.UserData24BlockState)
					{
						byte device = userDataBytes[2];
						byte address = userDataBytes[3];
						byte addressAddOn = userDataBytes[4];

						eAddressExtension_1 addressExtension;
						bool bRetVal = GenParse_AddressExtension.ParseByte_AddExt_1(userDataBytes[5], out addressExtension);
						if (bRetVal)
						{
							int nrOfBlockStateBytes = userDataBytes.Length - NrOfHeaderBytes;
							byte[] blockStateBytes = new byte[nrOfBlockStateBytes];
							for (int index = 0; index < nrOfBlockStateBytes; index++)
							{
								blockStateBytes[index] = userDataBytes[index + 6];
							}

							userData24BlockState = new UserData_24_BlockState(device, address, addressAddOn, addressExtension, blockStateBytes);
							consumedBytes = NrOfHeaderBytes + nrOfBlockStateBytes;
							return true;
						}
						
						// TODO handle error: ParseByte_AddExt_1 has failed
						return false;						
					}

					// TODO handle error: wrong value for the data type
					return false;
                }

				// TODO handle error: not enough bytes as specified by the SL value
				return false;
            }

			// TODO handle error (not enough header bytes)
            return false;
        }

        #endregion internal methods        
    }
}
